//------------------------------------------------------------------------------
// Copyright (c) 2008 www.dnaide.com
// Licensed under the MIT (MIT-LICENSE.txt)
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.IO;

using DNAide.Core;
using DNAide.Drawing;

namespace DNAide.Web.UI.Controls
{

	/// <summary>
	/// Control for transforming one source image into another image e.g. you supply a source image, apply a pixellate filter and the control saves this out to a file rendering a html image tag.
	/// </summary>
	public class ImageTransform : DNAideImageControl
	{

		#region Properties

		/// <summary>
		/// Source Image Path. 
		/// </summary>
		/// <remarks>
		/// Can be a url within the site or a file path e.g. ~/images/myimage.jpg or c:\images\myimage.jpg
		/// </remarks>
		public String SourceFileName
		{
			get { return ((ViewState["SourceFileName"] == null) ? string.Empty : (string)ViewState["SourceFileName"]); }
			set { ViewState["SourceFileName"] = value; }
		}

		/// <summary>
		/// Image Not Found Url
		/// If for some reason the source image does not exists, the control will return this image specified here.
		/// </summary>
		public String ImageNotFoundUrl
		{
			get { return ((ViewState["ImageNotFoundUrl"] == null) ? string.Empty : (string)ViewState["ImageNotFoundUrl"]); }
			set { ViewState["ImageNotFoundUrl"] = value; }
		}

		#endregion

		
		/// <summary>
		/// Raised when the source image has not been found
		/// </summary>
		public event EventHandler SourceImageNotFound;


		/// <summary>
		/// Set the source image to transform from a Stream
		/// </summary>
		/// <param name="stream"></param>
		public void SetBitmapToTransformFromStream(Stream stream)
		{
			BitmapToTransform = new Bitmap(stream);
		}


		/// <summary>
		/// Set the source image to transform from another bitmap
		/// </summary>
		/// <param name="bitmap"></param>
		public void SetBitmapToTransformFromBitmap(Bitmap bitmap)
		{
			BitmapToTransform = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), bitmap.PixelFormat);
		}


		/// <summary>
		/// </summary>
		protected override void SetFinalUrlAndPath()
		{
			if (string.IsNullOrEmpty(OutputFileName) && !string.IsNullOrEmpty(SourceFileName))
			{
				OutputFileName = Path.GetFileNameWithoutExtension(SourceFileName) + "_transformed" + Path.GetExtension(SourceFileName);
			}
			if (ViewState["OutputImageType"] == null)
			{
				// The output type has not been set. 
				// Try to determine, first from the OutputFileName, then the SourceFileName
				string extension = "";
				if (!string.IsNullOrEmpty(OutputFileName))
				{
					extension = Path.GetExtension(OutputFileName).ToLower();
				}
				if (string.IsNullOrEmpty(extension) && !string.IsNullOrEmpty(SourceFileName))
				{
					extension = Path.GetExtension(SourceFileName).ToLower();
				}
				if (!string.IsNullOrEmpty(extension))
				{
					SetCorrectOuputImageTypeFromExtension(extension);
				}
			}
			base.SetFinalUrlAndPath();
		}


		/// <summary>
		/// </summary>
		protected override void CreateOutput()
		{
			base.CreateOutput();

			string sourceFileName = SourceFileName;

			if (BitmapToTransform == null)
			{
				// Get the source from the supplied filename
				if (!sourceFileName.Contains(@"\"))
				{
					sourceFileName = HttpContext.Current.Server.MapPath(sourceFileName);
				}
				if (!File.Exists(sourceFileName))
				{
					// Source image does not exist, so return ImageNotFoundUrlNotFound
					if (!string.IsNullOrEmpty(ImageNotFoundUrl))
					{
						// And "ImageNotFoundUrlNotFound" has been set
						FinalUrl = UrlAide.Resolve(ImageNotFoundUrl);
					}
					else
					{
						throw new Exception(string.Format(Resources.ImageTransform.SourceOrAlternativeNotFound,sourceFileName,ImageNotFoundUrl));
					}
					// Raise event to indicate source image has not been found
					if (SourceImageNotFound != null) SourceImageNotFound(this, new EventArgs());
					SetFinalWidthAndHeight();
					return;
				}
			}

			if (string.IsNullOrEmpty(OutputDirectoryUrl))
			{
				OutputDirectoryUrl = DNAide.Configuration.DNAideConfigurationSettings.Web.CacheUrl + "/Images/Transformed";
			}

			SetFinalUrlAndPath();

			// Given the write options, determine whether we are ok to write the final image
			if (File.Exists(FinalPath))
			{
				if (OutputWriteOption == ImageWriteOptionType.IgnoreIfExists)
				{
					SetFinalWidthAndHeight();
					return;
				}
				else if (OutputWriteOption == ImageWriteOptionType.OverwriteIfSourceIsNewer)
				{
					if (File.Exists(FinalPath) && File.Exists(sourceFileName))
					{
						DateTime outputLastWriteTime = File.GetLastWriteTime(FinalPath);
						DateTime sourceLastWriteTime = File.GetLastWriteTime(sourceFileName);

						if (outputLastWriteTime > sourceLastWriteTime)
						{
							SetFinalWidthAndHeight();
							return;
						}
					}
				}
			}

			// Load the bitmap from the source file
			if (BitmapToTransform == null)
			{
				BitmapToTransform = BitmapAide.Load(sourceFileName);
			}

			// Raise event allowing the developer to apply any transformations
			RaiseApplyTransformationsEvent();

			// Save the file
			SaveFile();

			// Set final width and height.
			SetFinalWidthAndHeight(BitmapToTransform.Width, BitmapToTransform.Height);
		}


		#region Render Methods

		/// <summary>
		/// </summary>
		/// <param name="writer"></param>
		protected override void RenderAttributes(HtmlTextWriter writer)
		{
			this.Attributes.Remove("SourceFileName");
			this.Attributes.Remove("ImageNotFoundUrl");
			base.RenderAttributes(writer);
		}

		#endregion
	
	}
}
